from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
import Fun as F
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtUiTools import *
import openpyxl
import pandas as pd
import cv2
from openpyxl import Workbook
from ui.MainWindow import Ui_MainWindow
import plotly.graph_objects as go


class WorkThread(QThread):

    result_finish = Signal(bool,str)
    cur_status = Signal(int)

    def __init__(self, parent=None):
        super(WorkThread, self).__init__(parent)

    def run(self):
        if F.cap is None:
            self.result_finish.emit(False, '请先加载视频')
            return
        cap = cv2.VideoCapture(F.v_path)

        wb = Workbook()
        ws = wb.active
        ws['A1'] = '时间(ms)'
        ws["B1"] = "总和"
        ws["C1"] = "R"
        ws["D1"] = "G"
        ws["E1"] = "B"
        write_frame = 1
        IntervalFrame = F.IntervalFrame
        cur_frame = 1
        while True:
            ret, frame = cap.read()
            if not ret:
                break

            cur_frame += 1

            if IntervalFrame != 0:
                if(cur_frame % IntervalFrame != 0):
                    continue

            write_frame += 1
            self.cur_status.emit(cur_frame)

            avg_b = round(np.mean(frame[:, :, 0]))
            avg_g = round(np.mean(frame[:, :, 1]))
            avg_r = round(np.mean(frame[:, :, 2]))

            count  = avg_r + avg_g + avg_b
            ws[f'A{write_frame}'] = F.Interval * (cur_frame - 2)
            ws[f'B{write_frame}'] = count
            ws[f'C{write_frame}'] = avg_r
            ws[f'D{write_frame}'] = avg_g
            ws[f'E{write_frame}'] = avg_b
        wb.save('file.xlsx')
        self.result_finish.emit(True,"结束")


class MainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MainWindow,self).__init__(parent=None)
        self.setupUi(self)

        self.pb_analysis.clicked.connect(self.analysis)
        self.pB_load.clicked.connect(self.pB_load_V)
        self.pb_set_time.clicked.connect(self.set_time)
        self.pB_showtable.clicked.connect(self.show_biao)

    def set_time(self):
        try:
            if F.Interval is None:
                QMessageBox.information(self, "错误", "请先加载视频")
                return

            time = int(self.lE_time.text())
            if(time % F.Interval == 0):
                F.IntervalFrame = time / F.Interval
                self.lbl_time.setText(f'当前为{F.IntervalFrame * F.Interval}ms 请设置{F.Interval}倍数')
            else:
                QMessageBox.warning(self, '错误', '请设置整倍数')

        except Exception as e:
            QMessageBox.warning(self, '错误', f'设置时间失败 {str(e)}')


    def pB_load_V(self):
        file_path,_ = QFileDialog.getOpenFileName(self,'选择视频',"","视频文件(*.mp4);;所有文件(*.*)")
        if file_path:
            F.v_path = Path(file_path)
            self.lbl_V_path.setText(str(F.v_path))
            if(F.load_file() == False):
                QMessageBox.information(self,"错误","请确定加载文件为视频")


            self.lbl_time.setText(f'当前为{F.Interval * F.IntervalFrame}ms 请设置{F.Interval}倍数')

            self.lE_time.setText(str(F.Interval))

    def ms2hs(self,ms):
        # h = ms // (1000 * 60 * 60)
        # ms %= (1000 * 60 * 60)
        if ms < 0:
            return ms
        min = ms // (1000 * 60)
        ms %= (1000 * 60)

        sec = ms // 1000
        ms %= 1000
        return f'{int(min):02}:{int(sec) : 02}'


    def show_biao(self):
        df = pd.read_excel('file.xlsx')
        x = df.iloc[:,0]
        y_labels = df.columns[1:5]


        fig = go.Figure()
        colors = ['orange','red','green','blue']
        tick_vals = np.arange(start=min(x), stop=max(x) + 1, step=5000)
        tick_texts = [f'{self.ms2hs(i)} ms' for i in tick_vals]
        fig.update_layout(
            title=f'RGB分量及总和变化趋势 {int(F.Interval * F.IntervalFrame)}ms 间隔',
            xaxis=dict(
                rangeslider=dict(visible=False),
                title=df.columns[0],
                tickvals=tick_vals,
                ticktext=tick_texts,
                tickangle=45,
                tickmode="linear",
                # tick0 = min(x),
                range=[min(tick_vals), max(tick_vals)],
                dtick=5000,
            ),
            yaxis=dict(
                title="数据",
                range=[0, 400],
            ),
            hovermode='x unified'
        )

        for i,col in enumerate(y_labels):
            fig.add_trace(go.Scatter(x=x,
                                     y=df[col],
                                     mode='lines+markers',
                                     name=col,
                                     line=dict(color=colors[i]),
                                     hovertemplate=[
                                         f'{col}={v} {self.ms2hs(val)}<extra></extra>' for
                                         val, v in zip(x, df[col])]
                                     ))



        fig.show()

        # fig,ax = plt.subplots(figsize=(10,4))
        # plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
        # plt.rcParams['axes.unicode_minus'] = False
        # plt.axis('on')
        # plt.title(f'RGB分量及总和变化趋势 {int(F.Interval * F.IntervalFrame)}ms 间隔')
        # x = df.iloc[:,0]
        # xticks = np.arange(start=min(x), stop=max(x) + 1, step=5000)
        # xticks_label = [self.ms2hs(i) for i in xticks]
        # plt.xticks(ticks=xticks, labels=xticks_label,rotation=45)
        # plt.xlabel(df.columns[0],fontsize=20)
        # plt.ylabel('数值',fontsize=20)
        # plt.ylim(0,300)
        # plt.grid(True,linestyle='--',alpha=0.5)
        # colors = ['#1f77b4', '#ff0000', '#00ff00', '#0000ff']
        #
        # lines = []
        # for i, col in enumerate(df.columns[1:5]):
        #     line, = plt.plot(x, df[col], color=colors[i], label=col)
        #     lines.append(line)
        #
        #
        # plt.legend(fontsize=10)
        #
        # # 5. 添加交互功能
        #
        #
        # plt.tight_layout()
        # plt.show()
        # plt.savefig('file.png')

    def analysis_finish(self,status,msg):
        self.pb_analysis.setEnabled(True)
        if(status):
            self.lbl_status.setText("分析完成")
            self.show_biao()
        else:
            self.lbl_status.setText(f"错误！{msg}")


    def analysis_status(self,value):
        self.lbl_status.setText(f'{value}/{F.Total_Frame}')

    def analysis(self):
        self.thread = WorkThread(self)
        self.thread.result_finish.connect(self.analysis_finish)
        self.thread.cur_status.connect(self.analysis_status)
        self.pb_analysis.setEnabled(False)
        self.lbl_status.setText("分析中，请勿点击")
        self.thread.start()
